﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using JSC.Portal.Web;
using JSC.Portal.Data;
using JSC.Portal.Entities;
using JSC.Core;
using JSC.Core.Data;
using JSC.Portal.Module;
using JSC.Portal.Utils;
using JSC.Portal.Web.App.Modules.Articles.Entities;
using JSC.Portal.Web.App.Modules.Articles.Services;
using System.Web.UI.WebControls;

namespace JSC.Portal.Web.App.Modules.Articles
{
    public class ArticleModule : ServicedModule<IArticleService>
    {
        public ArticleModule(Section section) : base(section) 
        {
            Syndicatable = true;
        }

        public override void Load()
        {
            Dictionary<string, object> parameters = new Dictionary<string, object>();

            string query = "from Article a left join fetch a.ArticleCategory where a.Section.Id = :sectionid";

            parameters.Add("sectionid", Section.Id);
            Data.Add("Content", Service.GetByQuery(query, parameters));
        }

        public override void LoadById(int id)
        {
            Article a = Service.GetById(id, false);
            Data.Add("Content", a);
        }

        public override void LoadByIdAndPath(int id, string path)
        {
            Load();
        }

        public RssChannel GetRssFeedBySection()
        {
            IList<Article> articles = Service.GetRssArticles(Section, NumberOfArticlesInList, SortBy, SortDirection);
            RssChannel result = GetRssFeed(articles);
            return result;
        }

        public RssChannel GetRssFeedByCategory(ArticleCategory category)
        {
            IList<Article> articles = Service.GetRssArticlesByCategory(category, SortBy, SortDirection);
            RssChannel result = GetRssFeed(articles);
            return result;
        }

        private RssChannel GetRssFeed(IList<Article> articles)
        {
            RssChannel result = new RssChannel();
            result.Title = Section.Name;
            result.Description = Section.Description;
            result.Language = Section.Page.Language;
            result.PubDate = DateTime.Now;
            result.LastBuildDate = DateTime.Now;

            foreach (Article article in articles)
            {
                RssItem item = new RssItem();
                item.ItemId = article.Id;
                item.Title = article.Title;
                if (DisplayType == DisplayType.FullContent)
                {
                    item.Description = article.Content;
                }
                else
                {
                    item.Description = article.Description;
                }
                item.Author = (article.ModifiedByUser != null)
                    ? article.ModifiedByUser.FullName
                    : article.CreatedByUser.FullName;
                item.Category = (article.ArticleCategory != null)
                    ? article.ArticleCategory.Name
                    : string.Empty;
                item.PubDate = article.ValidFrom;
                result.RssItems.Add(item);
            }

            return result;
        }

        protected override void ReadSectionSettings()
        {
            base.ReadSectionSettings();

            try
            {
                string value = null;
                if (base.Section.TryGetSectionModulePropertyValue("ALLOW_COMMENTS", out value))
                    AllowComments = bool.Parse(value);
                if (base.Section.TryGetSectionModulePropertyValue("ALLOW_ANONYMOUS_COMMENTS", out value))
                    AllowAnonymousComments = bool.Parse(value);
                if (base.Section.TryGetSectionModulePropertyValue("ALLOW_SYNDICATION", out value))
                    AllowSyndication = bool.Parse(value);
                if (base.Section.TryGetSectionModulePropertyValue("SHOW_ARCHIVE", out value))
                    ShowArchive = bool.Parse(value);
                if (base.Section.TryGetSectionModulePropertyValue("SHOW_AUTHOR", out value))
                    ShowAuthor = bool.Parse(value);
                if (base.Section.TryGetSectionModulePropertyValue("SHOW_CATEGORY", out value))
                    ShowCategory = bool.Parse(value);
                if (base.Section.TryGetSectionModulePropertyValue("SHOW_DATETIME", out value))
                    ShowDateTime = bool.Parse(value);
                if (base.Section.TryGetSectionModulePropertyValue("NUMBER_OF_ARTICLES_IN_LIST", out value))
                    NumberOfArticlesInList = int.Parse(value);
                if (base.Section.TryGetSectionModulePropertyValue("DISPLAY_TYPE", out value))
                    DisplayType = (DisplayType)Enum.Parse(typeof(DisplayType), value);
                if (base.Section.TryGetSectionModulePropertyValue("SORT_BY", out value))
                    SortBy = (SortBy)Enum.Parse(typeof(SortBy), value);
                if (base.Section.TryGetSectionModulePropertyValue("SORT_DIRECTION", out value))
                    SortDirection = (SortDirection)Enum.Parse(typeof(SortDirection), value);
            }
            catch
            {
                // Only if the module settings are not in the database yet for some reason.
                SortBy = SortBy.ValidFrom;
                SortDirection = SortDirection.Descending;
            }
        }

        public bool AllowComments
        {
            get;
            private set;
        }

        public bool AllowAnonymousComments
        {
            get;
            private set;
        }

        public bool AllowSyndication
        {
            get;
            private set;
        }

        public bool ShowArchive
        {
            get;
            private set;
        }

        public bool ShowAuthor
        {
            get;
            private set;
        }

        public bool ShowCategory
        {
            get;
            private set;
        }

        public bool ShowDateTime
        {
            get;
            private set;
        }

        public int NumberOfArticlesInList
        {
            get;
            private set;
        }

        public DisplayType DisplayType
        {
            get;
            private set;
        }

        public SortDirection SortDirection
        {
            get;
            private set;
        }

        public SortBy SortBy
        {
            get;
            private set;
        }
    }
}
